const { resolve } = require('path'); // node 内置核心模块，用来处理路径问题，拼接绝对路径的方法
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 提取CSS成单独文件的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 压缩css,需下载npm install --save-dev optimize-css-assets-webpack-plugin
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin' )
// 生产环境配置
// 定义 nodejs 环境变量：决定使用 browserslist 的哪个环境 
process.env.NODE_ENV = 'production';
 // 复用 loader 
 const commonCssLoader = [ 
     MiniCssExtractPlugin.loader,
      'css-loader', { 
          // 还需要在 package.json 中定义 browserslist 
          loader: 'postcss-loader', 
          options: { 
              ident: 'postcss', 
              plugins: () => [require('postcss-preset-env')()] } } ];
// css 兼容性处理和压缩css
// 设置 nodejs 环境变量 
// process.env.NODE_ENV = 'development';
//  修改 package.json "browserslist": { "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ],"production": [ ">0.2%", "not dead", "not op_mini all" ] }

module.exports =
{ 
    entry: './src/js/index.js', // 入口文件 
    output: 
    { // 输出配置 
        filename: './built.js', // 输出文件名 
        path: resolve(__dirname, 'build/js') // 输出文件路径，// __dirname nodejs 的变量，代表当前文件的目录绝对路径
    },
    // 生产环境 的配置 
    module:
    { 
        rules: [ 
            {
             test: /\.css$/, 
             use: [...commonCssLoader] 
            },
            {
                test: /\.less$/, 
                use: [...commonCssLoader, 'less-loader'] 
            },/*正常来讲，一个文件只能被一个 loader 处理。 当一个文件要被多个 loader 处理，那么一定要指定 loader 执行的先后顺序：先执行 eslint 在执行 babel */
    // loader 的配置 
    // module: 
    // { 
    //     rules: 
    //         [ // 详细 loader 配置 // 不同文件必须配置不同 loader 处理 
    //             { // 匹配哪些文件 
    //                 test: /\.css$/,
    //                     // 使用哪些 loader 进行处理 
    //                 use: [ 
    //                     // use 数组中 loader 执行顺序：从右到左，从下到上 依次执行 // 创建 style 标签，将 js 中的样式资源插入进行，添加到 head 中生效
    //                     // 将 css 文件变成 commonjs 模块加载 js 中，里面内容是样式字符串 
    //                     'style-loader','css-loader' 
    //                     ] 
    //             },
    //             { 
    //                 test: /\.less$/, 
    //                 use: 
    //                     [ 
    //                         'style-loader', 
    //                         'css-loader', 
    //                     // 将 less 文件编译成 css 文件 // 需要下载 less-loader 和 less 
    //                         'less-loader' 
    //                     ] 
    //             },
    //             { // 问题：默认处理不了 html 中 img 图片 // 处理图片资源 
    //                 test: /\.(jpg|png|gif)$/, 
    //                 // 使用一个 loader // 下载 url-loader file-loader 
    //                 loader: 'url-loader', 
    //                 options: {
    //                     // 优点: 减少请求数量（减轻服务器压力） // 缺点：图片体积会更大（文件请求速度更慢） 
    //                     limit: 8 * 1024, 
    //                     // 问题：因为 url-loader 默认使用 es6 模块化解析，而 html-loader 引入图片是 commonjs // 解析时会出问题：[object Module] // 解决：关闭 url-loader 的 es6 模块化，使用 commonjs 解析 
    //                     esModule: false, // 给图片进行重命名 // [hash:10]取图片的 hash 的前 10 位 // [ext]取文件原来扩展名 
    //                     name: '[hash:10].[ext]' ,
    //                     outputPath: 'imgs'
    //                 } 
    //             },
    //             { 
    //                 test: /\.html$/, 
    //                 // 处理 html 文件的 img 图片（负责引入 img，从而能被 url-loader 进行处理） 
    //                 loader: 'html-loader' 
    //             },
    //             // 打包其他资源(除了 html/js/css 资源以外的资源) 
    //             { // 排除 css/js/html 资源 
    //                 exclude: /\.(css|js|html|less)$/, 
    //                 loader: 'file-loader', 
    //                 options: { name: '[hash:10].[ext]',
    //                 outputPath: 'media' } 
    //             },
    //             { 
    //                 // 提取 css 成单独文件
    //                 test: /\.css$/, 
    //                 use: [ // 创建 style 标签，将样式放入 // 'style-loader', // 这个 loader 取代 style-loader。作用：提取 js 中的 css 成单独文件 
    //                 MiniCssExtractPlugin.loader, // 将 css 文件整合到 js 文件中 
    //                 'css-loader',
    //                 { 
    //                     loader: 'postcss-loader', 
    //                     options: { 
    //                         ident: 'postcss', 
    //                         plugins: () => [ 
    //                             // postcss 的插件 
    //                             require('postcss-preset-env')() ] } }
                
    //             ] },
                // js 语法检查
                // 下载安装包 npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
                /*语法检查： eslint-loader eslint 注意：只检查自己写的源代码，第三方的库是不用检查的 设置检查规则： package.json 中 eslintConfig 中设置~ "eslintConfig": { "extends": "airbnb-base" } airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint */
                //  配置 package.json "eslintConfig": { "extends": "airbnb-base", "env": { "browser": true } }
                { 
                    test: /\.js$/, 
                    exclude: /node_modules/, 
                    loader: 'eslint-loader', 
                    options: { // 自动修复 eslint 的错误 
                        fix: true 

                    } 
                },
                 // js 兼容性处理,下载安装包
                // npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/polyfill core-js

                {
                    test: /\.js$/, 
                    exclude: /node_modules/, 
                    // 优先执行 
                    enforce: 'pre',
                    loader: 'babel-loader', 
                    options: { 
                        // 预设：指示 babel 做怎么样的兼容性处理 
                        presets: [ [ '@babel/preset-env', 
                        { // 按需加载 
                            useBuiltIns: 'usage', 
                            // 指定 core-js 版本 
                            corejs: { version: 3 },
                            // 指定兼容性做到哪个版本浏览器 
                            targets: { 
                                chrome: '60', 
                                firefox: '60', 
                                ie: '9', 
                                safari: '10',
                                edge: '17' 
                            } } ] ] } 
                },
               
            ]
    },
    // plugins 的配置 
    plugins: [ // 详细 plugins 的配置 
        // html-webpack-plugin // 功能：默认会创建一个空的 HTML，自动引入打包输出的所有资源（JS/CSS） // 需求：需要有结构的 HTML 文件
         new HtmlWebpackPlugin({ 
             // 复制 './src/index.html' 文件，并自动引入打包输出的所有资源（JS/CSS） 
             template: './src/index.html' 
            }),
            // 提取 css 成单独文件
            new MiniCssExtractPlugin({
                 // 对输出的 css 文件进行重命名 
                 filename: 'css/built.css' }),
                 // 压缩 css 
            new OptimizeCssAssetsWebpackPlugin()
    ],
    // HTML 压缩生产环境
    plugins: [ 
        new HtmlWebpackPlugin({ 
            template: './src/index.html', 
            // 压缩 html 代码 
            minify: { 
                // 移除空格
                 collapseWhitespace: true, 
                 // 移除注释 
                 removeComments: true } }) ],
   // 模式
    mode: 'development',//开发环境
     // js 压缩 
     // 生产环境下会自动压缩 js 代码 
    mode: 'production' };
    devServer: 
    // 运行指令: npx webpack-dev-server
    { // 项目构建后路径 
        contentBase: resolve(__dirname, 'build'), 
        // 启动 gzip 压缩
        compress: true, 
        // 端口号 
        port: 3000, 
        // 自动打开浏览器 
        open: true,
        // 开启 HMR 功能 // 当修改了 webpack 配置，新配置要想生效，必须重新 webpack 服务 
        hot: true, 
    
    }
    };
   
}
plugins: [
    new UglifyJsPlugin({
      // 允许并发
      parallel: true,
      // 开启缓存
      cache: true,
      compress: {
        // 删除所有的console语句    
        drop_console: true,
        // 把使用多次的静态值自动定义为变量
        reduce_vars: true,
      },
      output: {
        // 不保留注释
        comment: false,
        // 使输出的代码尽可能紧凑
        beautify: false
      }
    })
  ]
